<?php
// +---------------------------------------------------------------------+
// | OneBase    | [ WE CAN DO IT JUST THINK ]                            |
// +---------------------------------------------------------------------+
// | Licensed   | http://www.apache.org/licenses/LICENSE-2.0 )           |
// +---------------------------------------------------------------------+
// | Author     | 王勇程 <laughskydragon@qq.com>                        |
// +---------------------------------------------------------------------+
// | Repository | https://gitee.com/Bigotry/OneBase                      |
// +---------------------------------------------------------------------+

namespace app\common\logic;
use Intervention\Image\ImageManager;
use Intervention\Image\Drivers\Gd\Driver;

/**
 * 文件处理逻辑
 */
class File extends LogicBase
{
    
    /**
     * 图片上传
     * small,medium,big
     */
    public function pictureUpload($name = 'file', $thumb_config = ['small' => 100, 'medium' => 500, 'big' => 1000])
    {
        
        $object_info = request()->file($name);
        
        if (!$object_info || !$object_info->isValid()) {
            throw new \Exception('上传文件无效');
        }
        
        // 手动验证文件扩展名（ThinkPHP8中移除了validate方法）
        $allowed_ext = ['jpg', 'jpeg', 'png', 'gif'];
        $file_ext = strtolower($object_info->extension());
        if (!in_array($file_ext, $allowed_ext)) {
            throw new \Exception('图片后缀验证不通过，只允许：' . implode(',', $allowed_ext));
        }
        
        $sha1  = $object_info->hash();
        
        $picture_info = $this->modelPicture->getInfo(['sha1' => $sha1], 'id,name,path,sha1');
        
        if (!empty($picture_info)) { return $picture_info; }
        
        $save_name = $object_info->hashName();
        
        $saveNameArr = explode(DS, $save_name);

        // ThinkPHP8中move方法返回File对象
        $object = $object_info->move(PATH_PICTURE . $saveNameArr[0], $saveNameArr[1]);
        
        if (!$object) {
            throw new \Exception('文件移动失败');
        }
        
        $save_path = PATH_PICTURE . $save_name;
        
        $picture_dir_name = substr($save_name, 0, strrpos($save_name, DS));
        
        $filename = $saveNameArr[1];
        
        $thumb_dir_path = PATH_PICTURE . $picture_dir_name . DS . 'thumb';
        
        !file_exists($thumb_dir_path) && @mkdir($thumb_dir_path, 0777, true);
        
        // // 使用 Intervention/Image 处理图片
        // $manager = new ImageManager(new Driver());
        // $originalImage = $manager->read($save_path);

        // // 生成小尺寸缩略图
        // $resizedSmallImage = (clone $originalImage)->resize($thumb_config['small'][0], $thumb_config['small'][1]);
        // $this->saveImageWithExtension($resizedSmallImage, $thumb_dir_path . DS . 'small_' . $filename, $extension);

        // // 生成中尺寸缩略图
        // $resizedMediumImage = (clone $originalImage)->resize($thumb_config['medium'][0], $thumb_config['medium'][1]);
        // $this->saveImageWithExtension($resizedMediumImage, $thumb_dir_path . DS . 'medium_' . $filename, $extension);

        // // 生成大尺寸缩略图
        // $resizedBigImage = (clone $originalImage)->resize($thumb_config['big'][0], $thumb_config['big'][1]);
        // $this->saveImageWithExtension($resizedBigImage, $thumb_dir_path . DS . 'big_' . $filename, $extension);
        
        $data = ['name' => $filename, 'path' => $picture_dir_name . SYS_DS_PROS . $filename, 'sha1' => $sha1];
        
        $result = $this->modelPicture->setInfo($data);

        unset($object);

        $url = $this->checkStorage($result);
        
        if ($result) { $data['id'] = $result; $url && $data['url'] = $url; return $data; }
        
        return  false;
    }
    
    /**
     * 文件上传
     */
    public function fileUpload($name = 'file')
    {
        
        $object_info = request()->file($name);
        
        if (!$object_info || !$object_info->isValid()) {
            throw new \Exception('上传文件无效');
        }
        
        // 手动验证文件扩展名（ThinkPHP8中移除了validate方法）
        $allowed_ext = ['jpg', 'jpeg', 'png', 'gif', 'zip', 'rar', 'tar', 'gz', '7z', 'doc', 'docx', 'txt', 'xml', 'xlsx', 'xls', 'mp4'];
        $file_ext = strtolower($object_info->extension());
        if (!in_array($file_ext, $allowed_ext)) {
            throw new \Exception('文件后缀验证不通过，只允许：' . implode(',', $allowed_ext));
        }
        
        $sha1  = $object_info->hash();
        
        $file_info = $this->modelFile->getInfo(['sha1' => $sha1], 'id,name,path,sha1');
        
        if (!empty($file_info)) {
         
            return $file_info;
        }

        $save_name = $object_info->hashName();
        
        $saveNameArr = explode(DS, $save_name);

        // ThinkPHP8中move方法返回File对象
        $object = $object_info->move(PATH_PICTURE . $saveNameArr[0], $saveNameArr[1]);
        
        if (!$object) {
            throw new \Exception('文件移动失败');
        }
        
        $file_dir_name = substr($save_name, 0, strrpos($save_name, DS));
        
        $filename = $saveNameArr[1];
        
        $data = ['name' => $filename, 'path' => $file_dir_name . SYS_DS_PROS . $filename, 'sha1' => $sha1];
        
        $result = $this->modelFile->setInfo($data);

        unset($object);
        
        $url = $this->checkStorage($result, 'uploadFile');
        
        if ($result) {
            
            $data['id'] = $result;

            $url && $data['url'] = $url;
            
            return $data;
        }
        
        return  false;
    }
    
    /**
     * 云存储
     */
    public function checkStorage($result = 0, $method = 'uploadPicture')
    {
        
        $storage_driver = config('storage_driver');
        
        if (empty($storage_driver)) {
            
            return false;
        }
        
        $driver = SYS_DRIVER_DIR_NAME . $storage_driver;
        
        $storage_result = $this->serviceStorage->$driver->$method($result);
        
        $method != 'uploadPicture' ? $this->modelFile->setFieldValue(['id' => $result], 'url', $storage_result) : $this->modelPicture->setFieldValue(['id' => $result], 'url', $storage_result);

        return $storage_result;
    }
    
    /**
     * 获取图片URL路径
     */
    public function getPictureUrl($id = 0, $is_head = false)
    {
        
        $info = $this->modelPicture->getInfo(['id' => $id], 'path,url');
        
        if (!empty($info['url'])) {
            if(preg_match("/^http(s)?:\\/\\/.+/",$info['url'])){
                return $info['url'];
            }
            return config('static_domain') . SYS_DS_PROS . $info['url'];
        }

        $root_url = get_file_root_path();
        if (!empty($info['path'])) {
            $storage_driver = config('storage_driver');
            if (!empty($storage_driver)) {
                $driver = SYS_DRIVER_DIR_NAME . $storage_driver;
                $storage_result = $this->serviceStorage->$driver->config();
                if(isset($storage_result['domain'])){
                    return $storage_result['domain'] . '/upload/picture/'.$info['path'];
                }
            }
            if(config('static_domain')){
                return config('static_domain'). '/upload/picture/'.$info['path'];
            }else{
                return $root_url . 'upload/picture/'.$info['path'];
            }
        }

        if ($is_head) {

            return $root_url . 'static/module/admin/img/default_head.jpg';
        }

        return $root_url . 'static/module/admin/img/onimg.png';
    }
    
    /**
     * 获取文件URL路径
     */
    public function getFileUrl($id = 0)
    {
        
        $info = $this->modelFile->getInfo(['id' => $id], 'path,url');
        
        if (!empty($info['url'])) {
            if(preg_match("/^http(s)?:\\/\\/.+/",$info['url'])){
                return $info['url'];
            }
            return config('static_domain') . SYS_DS_PROS . $info['url'];
        }

        if (!empty($info['path'])) {

            $root_url = get_file_root_path();
            $storage_driver = config('storage_driver');
            if (!empty($storage_driver)) {
                $driver = SYS_DRIVER_DIR_NAME . $storage_driver;
                $storage_result = $this->serviceStorage->$driver->config();
                if(isset($storage_result['domain'])){
                    return $storage_result['domain'] . '/upload/file/'.$info['path'];
                }
            }
            if(config('static_domain')){
                return config('static_domain'). '/upload/file/'.$info['path'];
            }else{
                return $root_url . 'upload/file/'.$info['path'];
            }


        }

        return '暂无文件';
    }

    /**
     * 获取指定目录下的所有文件
     * @param string $path
     * @return array
     */
    public function getFileByPath($path = null)
    {
        $dirs = new \FilesystemIterator($path);
        $arr = [];
        foreach ($dirs as $v)
        {
            if($v->isdir())
            {
                $_arr = $this->getFileByPath($path ."/". $v->getFilename());
                $arr = array_merge($arr,$_arr);
            }else{
                $arr[] = $path . "/" . $v->getFilename();
            }
        }
        return $arr;
    }

    public function checkPictureExists($param = []) {
        return $this->modelPicture->getInfo(['sha1' => $param['sha1']], 'id,sha1');
    }

    public function checkFileExists($param = []) {
        return $this->modelFile->getInfo(['sha1' => $param['sha1']], 'id,sha1');
    }
    
    private function saveImageWithExtension($image, $path, $extension)
    {
        switch (strtolower($extension)) {
            case 'jpg':
            case 'jpeg':
                $image->toJpeg()->save($path);
                break;
            case 'png':
                $image->toPng()->save($path);
                break;
            case 'gif':
                $image->toGif()->save($path);
                break;
            default:
                // Fallback to JPEG if extension is not explicitly handled
                $image->toJpeg()->save($path);
                break;
        }
    }
}
